
#include "Hongo.h"
#include "../FabricasObjetosJuego.h"
#include <iostream>
#include <algorithm>

const int EstadoHongo::Aplastado = 0;
const int EstadoHongo::Chocado = 1;
const int EstadoHongo::SinParticular = 2;
const vector<int> EstadoHongo::acciones = make_vector<int>() << EstadoBasico::Movimiento;
const vector<string> EstadoHongo::descripcionAcciones = make_vector<string>() << "mover";
const vector<int> EstadoHongo::accionesParticulares = make_vector<int>() << EstadoHongo::Aplastado << EstadoHongo::Chocado;
const vector<string> EstadoHongo::descripcionAccionesParticulares = make_vector<string>() << "aplastar" << "chocar";

Hongo::Hongo(int x, int y, int maximoX, int maximoY, Orientacion orientacion) : ObjetoMovible(x, y, maximoX, maximoY, orientacion) {

	if (orientacion == Derecha)
		estadoDerecha = Empezo;
	else // if (orientacion == Izquierda)
		estadoIzquierda = Empezo;
		
	estado = EstadoBasico::Movimiento;
	estadoParticular = EstadoHongo::SinParticular;
	prioridad = 1;
	tipo = ENEMIGO;
	
	srand( time(NULL) );
}

void Hongo::Actualizar(Uint32 time) {

	if (estadoDerecha == Moviendo) {
		MoverDerecha(maximoX, time - lastTimeActualizar);
		if (getX() > maximoX) {
			setEstadoParticular(EstadoHongo::Aplastado);
			setActivo(false);
		}
	}
	
	if (estadoIzquierda == Moviendo) {
		MoverIzquierda(time - lastTimeActualizar);
		if (getX() + ancho < 0){
			setEstadoParticular(EstadoHongo::Aplastado);
			setActivo(false);
		}
	}
	
	if (estadoDerecha == Empezo) {
		estadoDerecha = Moviendo;
		setEstado(EstadoBasico::Movimiento);
	}
	
	if (estadoIzquierda == Empezo) {
		estadoIzquierda = Moviendo;
		setEstado(EstadoBasico::Movimiento);
	}
}

void Hongo::Detener() {
	estadoDerecha = SinMovimiento;
	estadoIzquierda = SinMovimiento;
}

pair<idImagen_t, int> Hongo::getDibujable(Uint32 time) {
	
	pair<idImagen_t, int> dibujable;
	
	if (estadoParticular == EstadoHongo::SinParticular) {
		dibujable = ObjetoMovible::getDibujable(time);
	}
	else {
		bool status = true;
		dibujable = getDibujableParticular(accionesParticulares.at(estadoParticular), time, &status);
		if (!status) {
			estadoVida = Muerto;
			if (rand() % 100 > 50 ) {
				FabricaBonus::CrearObjeto(getX(), getY(), orientacion);
			}
		}
	}
	
	return dibujable;
}

void Hongo::addAccionParticular(int idImagen, int cuadros) {
	Animacion *animacion = new Animacion (cuadros, 0, idImagen, ancho, alto);
    accionesParticulares.push_back(animacion);
}

void Hongo::Aplastar() {
	
	setEstadoParticular(EstadoHongo::Aplastado);
	setActivo(false);
	if (animacionActual < v_animaciones.size())
		v_animaciones.at(animacionActual)->Reiniciar();
	animacionActual = 0;
	waiting = false;
	
	estadoDerecha = SinMovimiento;
	estadoIzquierda = SinMovimiento;
}

void Hongo::Chocar() {
	
	estadoParticular = EstadoHongo::Chocado;
	if (animacionActual < v_animaciones.size())
		v_animaciones.at(animacionActual)->Reiniciar();
	animacionActual = 0;
	waiting = false;
	
	estadoDerecha = SinMovimiento;
	estadoIzquierda = SinMovimiento;
}

int Hongo::getEstadoParticular(){
	return estadoParticular;
}

void Hongo::setEstadoParticular(int estado) {
	estadoParticular = estado;
}

int Hongo::indexEstado(int estado) {
	
	vector<int> estados = EstadoHongo::acciones;
	
	unsigned int posicion = find(estados.begin(), estados.end(), estado) - estados.begin();
	
	if (posicion >= estados.size())
		return -1;
		
	return posicion;
}

void Hongo::Morir() {
	Chocar();
}

void Hongo::ColisionarConPersonaje(ObjetoEstatico* personaje, int colX, int colY, int colXvieja, int colYvieja) {

	Personaje* per = dynamic_cast<Personaje*> (personaje);

	per->StartSonido (SonidosPersonaje::Colision);

	if (per->getInvencibilidad()) {
		Morir();
		Frenar();
		return;
	}

	if (getEstadoParticular() == EstadoHongo::Aplastado) return;
	if (getEstadoParticular() == EstadoHongo::Chocado) return;

	if (colX > colY) {
		if (per->getVelocidadY() < 0) {
			Aplastar();
			Frenar();
			per->SumarPuntos(PUNTOS_SUMAR);
			per->setVelocidadY(120);
			per->setPosicion(per->getX(), getY() - per->getAlto());
		} else {
			per->RestarPuntos(PUNTOS_RESTAR);
			per->restarVida();
			CambiarSentido(1,1, true);
			setPosicion(getPosicionAnt().getX(), getPosicionAnt().getY());
		}
	} else {
		Morir();
		Frenar();
		per->RestarPuntos(PUNTOS_RESTAR);
		per->restarVida();
		CambiarSentido(1,1, true);
		setPosicion(getPosicionAnt().getX(), getPosicionAnt().getY());
	}
}

void Hongo::ColisionarConEnemigo(ObjetoEstatico* movible, int colX, int colY, int colXvieja, int colYvieja) {

	ObjetoMovible* mov = dynamic_cast<ObjetoMovible*> (movible);

	if (getPrioridad() < mov->getPrioridad()) mov->ColisionarConEnemigo(this, colX, colY, colXvieja, colYvieja);

	if (movible->getEstadoVida() == Muerto) return;

	else {
		if (colXvieja != 0) {
			if (mov->getVelocidadY() <= 0) movible->setPosicion(movible->getX(), getY() - movible->getAlto());
			else movible->setPosicion(movible->getX(), getY() + getAlto());
		}
		else if (colYvieja != 0) {
			CambiarSentido(getX(), getY(), true);
			mov->CambiarSentido(getX(), getAncho());
		}
		else {
			if (colX >= colY) {
				if (mov->getVelocidadY() <= 0) movible->setPosicion(movible->getX(), getY() - movible->getAlto());
				else movible->setPosicion(movible->getX(), getY() + getAlto());
			}
			else {
				CambiarSentido(getX(), getY(), true);
				mov->CambiarSentido(getX(), getAncho());
			}
		}
	}
}
